home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJLSR106.ARJ / FINDIOP.C < prev    next >
C/C++ Source or Header  |  1992-03-02  |  4KB  |  161 lines

  1. /* This is file FINDIOP.C */
  2. /* This file may have been modified by DJ Delorie (Jan 1991).  If so,
  3. ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
  4. ** Rochester NH, 03867-2954, USA.
  5. */
  6.  
  7. /*
  8.  * Copyright (c) 1983, 1985 Regents of the University of California.
  9.  * All rights reserved.  The Berkeley software License Agreement
  10.  * specifies the terms and conditions for redistribution.
  11.  */
  12.  
  13. #if defined(LIBC_SCCS) && !defined(lint)
  14. static char sccsid[] = "@(#)findiop.c    5.7 (Berkeley) 9/22/88";
  15. #endif LIBC_SCCS and not lint
  16.  
  17. #include <stdio.h>
  18. #include <errno.h>
  19. #include <fcntl.h>
  20.  
  21. extern int errno;
  22.  
  23. #define active(iop)    ((iop)->_flag & (_IOREAD|_IOWRT|_IORW))
  24.  
  25. #define NSTATIC    20    /* stdin + stdout + stderr + the usual */
  26.  
  27. FILE _iob[NSTATIC] = {
  28.     { 0, NULL, NULL, 0, _IOREAD|_IOTEXT,    0 },    /* stdin  */
  29.     { 0, NULL, NULL, 0, _IOWRT|_IOTEXT,    1 },    /* stdout */
  30.     { 0, NULL, NULL, 0, _IOWRT|_IONBF|_IOTEXT,2 },    /* stderr */
  31.     { 0, NULL, NULL, 0, _IOWRT|_IONBF,3 },        /* stdaux */
  32.     { 0, NULL, NULL, 0, _IOWRT|_IONBF,4 },        /* stdprn */
  33. };
  34.  
  35. extern    void    *calloc();
  36.  
  37. static    char sbuf[NSTATIC];
  38. char    *_smallbuf = sbuf;
  39. static    FILE    **iobglue;
  40. static    FILE    **endglue;
  41.  
  42. int setmode(int handle, int newmode)
  43. {
  44.   FILE *f, **fp;
  45.   int i;
  46.   for (i=0; i<NSTATIC; i++)
  47.     if (_iob[i]._file == handle)
  48.     {
  49.       f = _iob + i;
  50.       goto got_it;
  51.     }
  52.   if (!iobglue)
  53.     goto not_got_it;
  54.   for (fp=iobglue; fp<endglue; fp++)
  55.     if ((*fp)->_file == handle)
  56.     {
  57.       f = *fp;
  58.       break;
  59.     }
  60.  
  61. got_it:
  62.   if (newmode & O_BINARY)
  63.     f->_flag &= ~_IOTEXT;
  64.   else
  65.     f->_flag |= _IOTEXT;
  66.  
  67. not_got_it:
  68.   return _setmode(handle, newmode);
  69. }
  70.  
  71. /*
  72.  * Find a free FILE for fopen et al.
  73.  * We have a fixed static array of entries, and in addition
  74.  * may allocate additional entries dynamically, up to the kernel
  75.  * limit on the number of open files.
  76.  * At first just check for a free slot in the fixed static array.
  77.  * If none are available, then we allocate a structure to glue together
  78.  * the old and new FILE entries, which are then no longer contiguous.
  79.  */
  80. FILE *
  81. _findiop()
  82. {
  83.     register FILE **iov, *iop;
  84.     register FILE *fp;
  85.  
  86.     if (iobglue == 0) {
  87.         for (iop = _iob; iop < _iob + NSTATIC; iop++)
  88.             if (!active(iop))
  89.                 return (iop);
  90.  
  91.         if (_f_morefiles() == 0) {
  92.             errno = ENOMEM;
  93.             return (NULL);
  94.         }
  95.     }
  96.  
  97.     iov = iobglue;
  98.     while (*iov != NULL && active(*iov))
  99.         if (++iov >= endglue) {
  100.             errno = EMFILE;
  101.             return (NULL);
  102.         }
  103.  
  104.     if (*iov == NULL)
  105.         *iov = (FILE *)calloc(1, sizeof **iov);
  106.  
  107.     return (*iov);
  108. }
  109.  
  110. _f_morefiles()
  111. {
  112.     register FILE **iov;
  113.     register FILE *fp;
  114.     register char *cp;
  115.     int nfiles;
  116.  
  117.     nfiles = getdtablesize();
  118.  
  119.     iobglue = (FILE **)calloc(nfiles, sizeof *iobglue);
  120.     if (iobglue == NULL)
  121.         return (0);
  122.  
  123.     endglue = iobglue + nfiles;
  124.  
  125.     for (fp = _iob, iov = iobglue; fp < &_iob[NSTATIC]; /* void */)
  126.         *iov++ = fp++;
  127.  
  128.     _smallbuf = calloc(nfiles, sizeof(*_smallbuf));
  129.     return (1);
  130. }
  131.  
  132. f_prealloc()
  133. {
  134.     register FILE **iov;
  135.     register FILE *fp;
  136.  
  137.     if (iobglue == NULL && _f_morefiles() == 0)
  138.         return;
  139.  
  140.     for (iov = iobglue; iov < endglue; iov++)
  141.         if (*iov == NULL)
  142.             *iov = (FILE *)calloc(1, sizeof **iov);
  143. }
  144.  
  145. _fwalk(function)
  146.     register int (*function)();
  147. {
  148.     register FILE **iov;
  149.     register FILE *fp;
  150.  
  151.     if (iobglue == NULL) {
  152.         for (fp = _iob; fp < &_iob[NSTATIC]; fp++)
  153.             if (active(fp))
  154.                 (*function)(fp);
  155.     } else {
  156.         for (iov = iobglue; iov < endglue; iov++)
  157.             if (*iov && active(*iov))
  158.                 (*function)(*iov);
  159.     }
  160. }
  161.